﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Users
{
	/// <summary>
	/// 
	/// </summary>
	public static class Utility
	{
		private static readonly byte[] AesKey;
		private static readonly byte[] AesIV;

		static Utility()
		{
			string base64AesKey = "Yn/awqNMK7inxkVWtXXqRfJbMYve8AyOfUOwMrIy1/U=";
			string base64AesIV = "xPTGFiiauxVD89yYm2Sl5w==";
			AesKey = Convert.FromBase64String(base64AesKey);
			AesIV = Convert.FromBase64String(base64AesIV);
		}

		/// <summary>
		/// 验证参数。
		/// </summary>
		/// <param name="param">参数。</param>
		/// <param name="minSize">最小长度。</param>
		/// <param name="maxSize">最大长度。</param>
		/// <returns></returns>
		public static Boolean ValidateParameter(string param, int minSize, int maxSize)
		{
			string regexPattern = "[\u4e00-\u9fa5]";
			var matches = Regex.Matches(param, regexPattern);
			int size = param.Length + matches.Count;

			return size >= minSize && size <= maxSize;
		}

		/// <summary>
		/// 验证用户名格式。
		/// </summary>
		/// <param name="username">用户名。</param>
		/// <returns></returns>
		public static Boolean ValidateUsernameFormat(string username)
		{
			if (username == null) return false;

			// 长度限制
			if (!ValidateParameter(username, 4, 30))
			{
				return false;
			}

			// 字符限制
			// a-z, 0-9, 中文, 下划线。以a-z或中文开始
			string regexPattern = "^[a-z|\u4e00-\u9fa5][a-z|\u4e00-\u9fa5|0-9|_]*$";
			if (!Regex.IsMatch(username.ToLower(), regexPattern)) return false;

			return true;
		}

		/// <summary>
		/// 验证密码格式。
		/// </summary>
		/// <param name="password">密码。</param>
		/// <returns></returns>
		public static Boolean ValidatePasswordFormat(string password)
		{
			if (password == null) return false;

			// 长度限制
			if (!ValidateParameter(password, 6, 30))
			{
				return false;
			}

			// 字符限制
			// 键盘上能输入的所有可见字符。A-Z、a-z、0-9、~!@#$%^&*()_+{}|:”<>?`-=[]\;’,./
			string regexPattern = @"^[A-Za-z0-9~!@#\$%\^&\*\(\)_\+{}\|:""<>\?`\-=\[\]\\;',\./]*$";
			if (!Regex.IsMatch(password, regexPattern)) return false;

			return true;
		}

		/// <summary>
		/// 验证电子邮箱。
		/// </summary>
		/// <param name="email">电子邮箱。</param>
		/// <returns></returns>
		public static Boolean ValidateEmailFormat(string email)
		{
			if (String.IsNullOrEmpty(email)) return false;

			// 电子邮箱格式
			string regexPattern = @"^[a-z|0-9|_\.]*@[a-z|0-9|-]*\.[a-z]{2,6}$";
			if (!Regex.IsMatch(email.ToLower(), regexPattern)) return false;

			return true;
		}

		/// <summary>
		/// 验证手机号码。
		/// </summary>
		/// <param name="mobile">手机号码。</param>
		/// <returns></returns>
		public static Boolean ValidateMobileFormat(string mobile)
		{
			if (String.IsNullOrEmpty(mobile)) return false;

			// 手机号码格式
			string regexPattern = @"^(13\d|15\d|18\d)\d{8}$";
			if (!Regex.IsMatch(mobile, regexPattern)) return false;

			return true;
		}

		/// <summary>
		/// 当字符串对象为空(null or empty)时抛出异常。
		/// </summary>
		/// <param name="value">一个String值。</param>
		/// <param name="throwMessage">排除异常时的消息。</param>
		public static void ThrowNullOrEmpty(string value, string throwMessage)
		{
			if (String.IsNullOrEmpty(value))
			{
				if (String.IsNullOrEmpty(throwMessage))
				{
					throwMessage = "参数不能为空";
				}
				throw new Exception(throwMessage);
			}
		}

		/// <summary>
		/// AES加密数据。
		/// </summary>
		/// <param name="inputData">要被加密的数据。</param>
		/// <param name="key">机密密钥。</param>
		/// <param name="iv">初始向量。</param>
		/// <returns>返回加密后的数据。</returns>
		public static byte[] AesEncrypt(byte[] inputData, byte[] key, byte[] iv)
		{
			AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
			ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);

			MemoryStream encryptedStream = new MemoryStream();
			CryptoStream cryptoStream = new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);

			cryptoStream.Write(inputData, 0, inputData.Length);
			cryptoStream.FlushFinalBlock();

			return encryptedStream.ToArray();
		}

		/// <summary>
		/// AES加密。使用内置的机密密钥和初始向量加密。
		/// </summary>
		/// <param name="inputData">要被加密的数据。</param>
		/// <returns>返回加密后的数据。</returns>
		public static byte[] AesEncrypt(byte[] inputData)
		{
			return AesEncrypt(inputData, AesKey, AesIV);
		}

		/// <summary>
		/// AES加密。并将其转化为Base64返回。
		/// </summary>
		/// <param name="inputData">要被加密的数据。</param>
		/// <param name="key">机密密钥。</param>
		/// <param name="iv">初始向量。</param>
		/// <returns>返回加密后的数据,Base64形式。</returns>
		public static string AesEncryptAndToBase64(byte[] inputData, byte[] key, byte[] iv)
		{
			byte[] buffer = AesEncrypt(inputData, key, iv);
			return Convert.ToBase64String(buffer);
		}

		/// <summary>
		/// AES加密。并将其转化为Base64返回。使用内置的机密密钥和初始向量加密。
		/// </summary>
		/// <param name="inputData">要被加密的数据。</param>
		/// <returns>返回加密后的数据，Base64。</returns>
		public static string AesEncryptAndToBase64(byte[] inputData)
		{
			return AesEncryptAndToBase64(inputData, AesKey, AesIV);
		}

		/// <summary>
		/// AES解密。
		/// </summary>
		/// <param name="encryptedData">要被解密的数据。</param>
		/// <param name="key">机密密钥。</param>
		/// <param name="iv">初始向量。</param>
		/// <returns>返回解密后的数据。</returns>
		public static byte[] AesDecrypt(byte[] encryptedData, byte[] key, byte[] iv)
		{
			AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
			ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);

			MemoryStream encryptedStream = new MemoryStream();
			encryptedStream.Write(encryptedData, 0, encryptedData.Length);
			encryptedStream.Position = 0;

			CryptoStream cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
			BinaryReader reader = new BinaryReader(cryptoStream);
			List<byte> decryptedData = new List<byte>();

			while (true)
			{
				int data = cryptoStream.ReadByte();
				if (data != -1)
				{
					decryptedData.Add((byte)data);
				}
				else
				{
					break;
				}

			}

			return decryptedData.ToArray();
		}

		/// <summary>
		/// AES解密。使用内置的机密密钥和初始向量加密。
		/// </summary>
		/// <param name="encryptedData">要被解密的数据。</param>
		/// <returns>返回解密后的数据。</returns>
		public static byte[] AesDecrypt(byte[] encryptedData)
		{
			return AesDecrypt(encryptedData, AesKey, AesIV);
		}

		/// <summary>
		/// AES解密。从Base64字符串中解密。
		/// </summary>
		/// <param name="base64String">要被解密的Base64字符串。</param>
		/// <param name="key">机密密钥。</param>
		/// <param name="iv">初始向量。</param>
		/// <returns>返回解密后的数据。</returns>
		public static byte[] AesDecryptFromBase64(string base64String, byte[] key, byte[] iv)
		{
			byte[] encryptedData = Convert.FromBase64String(base64String);
			return AesDecrypt(encryptedData, key, iv);
		}

		/// <summary>
		/// AES解密。从Base64字符串中解密。使用内置的机密密钥和初始向量加密。
		/// </summary>
		/// <param name="encryptedData">要被解密的数据。</param>
		/// <returns>返回解密后的数据。</returns>
		public static byte[] AesDecryptFromBase64(string base64String)
		{
			return AesDecryptFromBase64(base64String, AesKey, AesIV);
		}

		public static string QueryStringToJson(string value)
		{
			string[] kvs = value.Split('&');
			Dictionary<string, string> dict = new Dictionary<string, string>();

			foreach (var item in kvs)
			{
				string[] kv = item.Split('=');
				string k = kv[0];
				string v = HttpUtility.UrlDecode(kv[1]);
				dict.Add(k, v);
			}

			return ConvertToJson(dict);
		}

		public static string ConvertToJson(Dictionary<string, string> dict)
		{
			string json = null;
			foreach (var kv in dict)
			{
				if (json == null)
				{
					json = "\"" + kv.Key + "\":\"" + kv.Value + "\"";
				}
				else
				{
					json += ",\"" + kv.Key + "\":\"" + kv.Value + "\"";
				}
			}
			return "{" + json + "}";
		}
	}

}
